﻿using Dapper;
using JX.Core;
using JX.Core.Entity;
using JX.Infrastructure.Attribute;
using JX.Infrastructure.Common;
using JX.Infrastructure.Data;
using JX.Infrastructure.Field;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace JX.Dapper
{
	/// <summary>
	/// 仓储实现类
	/// </summary>
	public abstract class RepositoryDapper<T> : IRepositoryDapper<T> where T : class, new()
	{
		#region 数据上下文
		/// <summary>
		/// 数据上下文
		/// </summary>
		protected DapperDBContext _Context { get; private set; }
		/// <summary>
		/// DbContext的工厂类
		/// </summary>
		protected IDapperDBContextFactory _DbContextFactory { get; private set; }
		/// <summary>
		/// 构造器注入
		/// </summary>
		/// <param name="Context"></param>
		/// <param name="dbContextFactory"></param>
		public RepositoryDapper(DapperDBContext Context, IDapperDBContextFactory dbContextFactory)
		{
			_Context = Context;
			_DbContextFactory = dbContextFactory;
		}
		#endregion

		#region 得到第一行第一列的值
		/// <summary>
		/// 直接获取特定一个或者多个字段的值,多个字段需要声明Model。
		/// 例：var s = testDal.GetScalar《string》(m=>m.Name,m=>m.Code==1,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// var s = testDal.GetScalar《StoreM》(m=>new StoreM { Name1= m.Name, Code=m.Code },m=>m.Code==2,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// var s = testDal.GetScalar《dynamic》(m=>new { m.Name,m.Code },m=>m.Code==3,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// </summary>
		/// <typeparam name="TResult">数据结果</typeparam>
		/// <param name="scalar">要返回的结果，Lamda表达式（p=>p.Id）</param>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual TResult GetScalar<TResult>(Expression<Func<T, TResult>> scalar,
			Expression<Func<T, bool>> predicate = null,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var sqlSelect = scalar.GetQueryField();
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			var sqlWhere = predicate.GetWhereSql(listSqlParaModel);
			var sqlOrderBy = orderby.GetOrderBySql();
			string strSQL = "select " + sqlSelect + " from " + GetTableName() + sqlWhere + sqlOrderBy;
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.QueryFirstOrDefault<TResult>(strSQL, GetDynamicParameters(listSqlParaModel));
		}
		/// <summary>
		/// 直接获取特定一个或者多个字段的值,多个字段需要声明Model。
		/// 例：var s = testDal.GetScalar《string》(m=>m.Name,m=>m.Code==1,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// var s = testDal.GetScalar《StoreM》(m=>new StoreM { Name1= m.Name, Code=m.Code },m=>m.Code==2,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// var s = testDal.GetScalar《dynamic》(m=>new { m.Name,m.Code },m=>m.Code==3,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// </summary>
		/// <typeparam name="TResult">数据结果</typeparam>
		/// <param name="scalar">要返回的结果，Lamda表达式（p=>p.Id）</param>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<TResult> GetScalarAsync<TResult>(Expression<Func<T, TResult>> scalar,
			Expression<Func<T, bool>> predicate = null,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var sqlSelect = scalar.GetQueryField();
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			var sqlWhere = predicate.GetWhereSql(listSqlParaModel);
			var sqlOrderBy = orderby.GetOrderBySql();
			string strSQL = "select " + sqlSelect + " from " + GetTableName() + sqlWhere + sqlOrderBy;
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.QueryFirstOrDefaultAsync<TResult>(strSQL, GetDynamicParameters(listSqlParaModel));
		}

		/// <summary>
		/// 得到第一行第一列的值
		/// </summary>
		/// <typeparam name="TResult">数据结果</typeparam>
		/// <param name="statistic">要返回的字段（如：count(*) 或者 UserName）</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual TResult GetScalar<TResult>(string statistic, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			if (string.IsNullOrWhiteSpace(statistic))
			{
				statistic = "count(*)";
			}
			string strSQL = "select " + statistic + " from " + GetTableName() + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.ExeSQLScalar<TResult>(strSQL, param);
		}
		/// <summary>
		/// 得到第一行第一列的值（异步方式）
		/// </summary>
		/// <typeparam name="TResult">数据结果</typeparam>
		/// <param name="statistic">要返回的字段（如：count(*) 或者 UserName）</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<TResult> GetScalarAsync<TResult>(string statistic, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			if (string.IsNullOrWhiteSpace(statistic))
			{
				statistic = "count(*)";
			}
			string strSQL = "select " + statistic + " from " + GetTableName() + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.ExeSQLScalarAsync<TResult>(strSQL, param);
		}
		#endregion

		#region 得到所有行数
		/// <summary>
		/// 得到所有行数
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual int GetCount(Expression<Func<T, bool>> predicate, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var sqlSelect = "count(*)";
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			string strSQL = "select " + sqlSelect + " from " + GetTableName() + sqlWhere;
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.ExeSQLScalar<int>(strSQL, GetDynamicParameters(listSqlParaModel));
		}
		/// <summary>
		/// 得到所有行数
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<int> GetCountAsync(Expression<Func<T, bool>> predicate, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var sqlSelect = "count(*)";
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			string strSQL = "select " + sqlSelect + " from " + GetTableName() + sqlWhere;
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.ExeSQLScalarAsync<int>(strSQL, GetDynamicParameters(listSqlParaModel));
		}
		/// <summary>
		/// 得到所有行数
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual int GetCount(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetScalar<int>("count(*)", strWhere, param, writeAndRead);
		}
		/// <summary>
		/// 得到所有行数（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<int> GetCountAsync(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return await GetScalarAsync<int>("count(*)", strWhere, param, writeAndRead);
		}
		#endregion

		#region 得到最大ID、最新ID
		/// <summary>
		/// 得到数据表中第一个主键的最大数值
		/// </summary>
		/// <returns></returns>
		public virtual int GetMaxID()
		{
			return GetScalar<int>("max("+ AttrHelper.GetKeyName<T>() + ")",string.Empty,null,WriteAndReadEnum.Write);
		}
		/// <summary>
		/// 得到数据表中第一个主键的最大数值（异步方式）
		/// </summary>
		/// <returns></returns>
		public virtual async Task<int> GetMaxIDAsync()
		{
			return await GetScalarAsync<int>("max(" + AttrHelper.GetKeyName<T>() + ")", string.Empty, null, WriteAndReadEnum.Write);
		}

		/// <summary>
		/// 得到数据表中第一个主键的最大数值加1
		/// </summary>
		/// <returns></returns>
		public virtual int GetNewID()
		{
			return GetMaxID() + 1;
		}
		/// <summary>
		/// 得到数据表中第一个主键的最大数值加1（异步方式）
		/// </summary>
		/// <returns></returns>
		public virtual async Task<int> GetNewIDAsync()
		{
			return await GetMaxIDAsync() + 1;
		}
		#endregion

		#region 验证是否存在
		/// <summary>
		/// 验证当前条件是否存在相同项
		/// </summary>
		/// <param name="predicate"></param>
		/// <returns></returns>
		public virtual bool IsExist(Expression<Func<T, bool>> predicate)
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			return IsExist(sqlWhere, GetDynamicParameters(listSqlParaModel));
		}
		/// <summary>
		/// 验证当前条件是否存在相同项（异步方式）
		/// </summary>
		/// <param name="predicate"></param>
		/// <returns></returns>
		public virtual async Task<bool> IsExistAsync(Expression<Func<T, bool>> predicate)
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			return await IsExistAsync(sqlWhere, GetDynamicParameters(listSqlParaModel));
		}
		/// <summary>
		/// 检查数据是否存在
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		public virtual bool IsExist(string strWhere = "", object param = null)
		{
			if (GetCount(strWhere, param,WriteAndReadEnum.Write) == 0)
			{
				return false;
			}
			return true;
		}
		/// <summary>
		/// 检查数据是否存在（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		public virtual async Task<bool> IsExistAsync(string strWhere = "", object param = null)
		{
			int count = await GetCountAsync(strWhere, param, WriteAndReadEnum.Write);
			if (count == 0)
			{
				return false;
			}
			return true;
		}
		#endregion

		#region 添加
		/// <summary>
		/// 增加一条记录
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		public virtual bool Add(T entity)
		{
			if (entity == null) return false;
			string strSQL = Query.GetInsertTableSql<T>(GetTableName());
			return _Context.Execute(strSQL, entity) > 0;
		}
		/// <summary>
		/// 增加一条记录（异步方式）
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		public virtual async Task<bool> AddAsync(T entity)
		{
			if (entity == null) return false;
			string strSQL = Query.GetInsertTableSql<T>(GetTableName());
			return await _Context.ExecuteAsync(strSQL, entity) > 0;
		}

		/// <summary>
		/// 增加多条记录，同一模型
		/// </summary>
		/// <param name="entityList">实体模型集合</param>
		/// <returns></returns>
		public virtual bool AddList(IList<T> entityList)
		{
			if (entityList == null || entityList.Count == 0) return false;
			string strSQL = Query.GetBatchInsertTableSql<T>(GetTableName(), entityList);
			return _Context.Execute(strSQL) > 0;
		}
		/// <summary>
		/// 增加多条记录，同一模型（异步方式）
		/// </summary>
		/// <param name="entityList">实体模型集合</param>
		/// <returns></returns>
		public virtual async Task<bool> AddListAsync(IList<T> entityList)
		{
			if (entityList == null || entityList.Count == 0) return false;
			string strSQL = Query.GetBatchInsertTableSql<T>(GetTableName(), entityList);
			return await _Context.ExecuteAsync(strSQL) > 0;
		}

		/// <summary>
		/// 增加一条记录，返回新的ID号。需要有一个单一主键，并且开启有标识符属性
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		public virtual int Insert(T entity)
		{
			if (entity == null) return -1;
			string strSQL = Query.GetInsertTableSql<T>(GetTableName());
			strSQL += "; SELECT CAST(SCOPE_IDENTITY() as int)";
			return _Context.Query<int>(strSQL, entity).FirstOrDefault();
		}
		/// <summary>
		/// 增加一条记录，返回新的ID号。需要有一个单一主键，并且开启有标识符属性（异步方式）
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		public virtual async Task<int> InsertAsync(T entity)
		{
			if (entity == null) return -1;
			string strSQL = Query.GetInsertTableSql<T>(GetTableName());
			strSQL += "; SELECT CAST(SCOPE_IDENTITY() as int)";
			var result = await _Context.QueryAsync<int>(strSQL, entity);
			return result.FirstOrDefault();
		}

		/// <summary>
		/// 增加或更新一条记录
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <param name="IsSave">是否增加</param>
		/// <returns></returns>
		public virtual bool AddOrUpdate(T entity, bool IsSave)
		{
			return IsSave ? Add(entity) : Update(entity);
		}
		/// <summary>
		/// 增加或更新一条记录（异步方式）
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <param name="IsSave">是否增加</param>
		/// <returns></returns>
		public virtual async Task<bool> AddOrUpdateAsync(T entity, bool IsSave)
		{
			return IsSave ? await AddAsync(entity) : await UpdateAsync(entity);
		}
		#endregion

		#region 删除
		/// <summary>
		/// 通过Lamda表达式，删除一条或多条记录
		/// </summary>
		/// <param name="predicate">Lamda表达式（p=>p.Id==Id）</param>
		/// <returns></returns>
		public virtual bool Delete(Expression<Func<T, bool>> predicate)
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			return Delete(sqlWhere, GetDynamicParameters(listSqlParaModel));
		}
		/// <summary>
		/// 通过Lamda表达式，删除一条或多条记录（异步方式）
		/// </summary>
		/// <param name="predicate">Lamda表达式（p=>p.Id==Id）</param>
		/// <returns></returns>
		public virtual async Task<bool> DeleteAsync(Expression<Func<T, bool>> predicate)
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			return await DeleteAsync(sqlWhere, GetDynamicParameters(listSqlParaModel));
		}
		/// <summary>
		/// 删除一条或多条记录
		/// </summary>
		/// <param name="strWhere">参数化删除条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		public virtual bool Delete(string strWhere = "", object param = null)
		{
			string strSQL = "delete from " + GetTableName() + GetSqlWhere(strWhere);
			return _Context.Execute(strSQL, param) > 0;
		}
		/// <summary>
		/// 删除一条或多条记录（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化删除条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		public virtual async Task<bool> DeleteAsync(string strWhere = "", object param = null)
		{
			string strSQL = "delete from " + GetTableName() + GetSqlWhere(strWhere);
			return await _Context.ExecuteAsync(strSQL, param) > 0;
		}
		#endregion

		#region 修改
		/// <summary>
		/// 更新一条记录
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		public virtual bool Update(T entity)
		{
			if (entity == null) return false;
			string strSQL = Query.GetUpdataSql<T>(GetTableName());
			return _Context.Execute(strSQL, entity) > 0;
		}
		/// <summary>
		/// 更新一条记录（异步方式）
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		public virtual async Task<bool> UpdateAsync(T entity)
		{
			if (entity == null) return false;
			string strSQL = Query.GetUpdataSql<T>(GetTableName());
			return await _Context.ExecuteAsync(strSQL, entity) > 0;
		}
		/// <summary>
		/// 修改一条或多条记录
		/// </summary>
		/// <param name="strColumns">参数化要修改的列（如：ID = @ID,Name = @Name）</param>
		/// <param name="strWhere">参数化修改条件(例如: and ID = @ID)</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		public virtual bool Update(string strColumns, string strWhere = "", object param = null)
		{
			if (string.IsNullOrEmpty(strColumns))
				return false;

			string strSQL = "Update "+ GetTableName() + " SET " + strColumns + GetSqlWhere(strWhere);
			return _Context.Execute(strSQL, param) > 0;
		}
		/// <summary>
		/// 修改一条或多条记录（异步方式）
		/// </summary>
		/// <param name="strColumns">参数化要修改的列（如：ID = @ID,Name = @Name）</param>
		/// <param name="strWhere">参数化修改条件(例如: and ID = @ID)</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		public virtual async Task<bool> UpdateAsync(string strColumns, string strWhere = "", object param = null)
		{
			if (string.IsNullOrEmpty(strColumns))
				return false;

			string strSQL = "Update " + GetTableName() + " SET " + strColumns + GetSqlWhere(strWhere);
			return await _Context.ExecuteAsync(strSQL, param) > 0;
		}
		/// <summary>
		/// 批量更新
		/// </summary>
		/// <param name="entityList"></param>
		/// <returns></returns>
		public virtual bool UpdateList(IList<T> entityList)
		{
			if (entityList == null || entityList.Count == 0) return false;
			string strSQL = Query.GetUpdataSql<T>(GetTableName());
			return _Context.Execute(strSQL, entityList) > 0;
		}
		/// <summary>
		/// 批量更新
		/// </summary>
		/// <param name="entityList"></param>
		/// <returns></returns>
		public virtual async Task<bool> UpdateListAsync(IList<T> entityList)
		{
			if (entityList == null || entityList.Count == 0) return false;
			string strSQL = Query.GetUpdataSql<T>(GetTableName());
			return await _Context.ExecuteAsync(strSQL, entityList) > 0;
		}
		#endregion

		#region 得到实体
		/// <summary>
		/// 通过Lamda表达式获取实体
		/// </summary>
		/// <param name="predicate">Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual T Get(Expression<Func<T, bool>> predicate, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			return Get(sqlWhere, GetDynamicParameters(listSqlParaModel), writeAndRead);
		}
		/// <summary>
		/// 通过Lamda表达式获取实体（异步方式）
		/// </summary>
		/// <param name="predicate">Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<T> GetAsync(Expression<Func<T, bool>> predicate, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			return await GetAsync(sqlWhere, GetDynamicParameters(listSqlParaModel), writeAndRead);
		}
		/// <summary>
		/// 获取实体
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual T Get(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string strSQL = "select top 1 * from " + GetTableName() + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			var result = dbContext.QueryFirstOrDefault<T>(strSQL, param);
			return result;
		}
		/// <summary>
		/// 获取实体（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<T> GetAsync(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string strSQL = "select top 1 * from " + GetTableName() + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			var result = await dbContext.QueryFirstOrDefaultAsync<T>(strSQL, param);
			return result;
		}
		/// <summary>
		/// 获取实体
		/// </summary>
		/// <param name="strJoin">联合查询语句(例：inner join tablename t on t.id=t1.id)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual T Get(string strJoin, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string strSQL = "select top 1 * from " + GetTableName() + " " + strJoin + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			var result = dbContext.QueryFirstOrDefault<T>(strSQL, param);
			return result;
		}
		/// <summary>
		/// 获取实体（异步方式）
		/// </summary>
		/// <param name="strJoin">联合查询语句(例：inner join tablename t on t.id=t1.id)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<T> GetAsync(string strJoin, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string strSQL = "select top 1 * from " + GetTableName() + " " + strJoin + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			var result = await dbContext.QueryFirstOrDefaultAsync<T>(strSQL, param);
			return result;
		}
		#endregion

		#region 得到实体列表
		/// <summary>
		/// 得到实体列表
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetList(Expression<Func<T, bool>> predicate,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			string sqlOrderBy = (orderby == null) ? string.Empty : orderby.GetOrderBySql();
			return GetList(sqlWhere + sqlOrderBy, GetDynamicParameters(listSqlParaModel), writeAndRead);
		}
		/// <summary>
		/// 得到实体列表
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<IEnumerable<T>> GetListAsync(Expression<Func<T, bool>> predicate,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			string sqlOrderBy = (orderby == null) ? string.Empty : orderby.GetOrderBySql();
			return await GetListAsync(sqlWhere + sqlOrderBy, GetDynamicParameters(listSqlParaModel), writeAndRead);
		}
		/// <summary>
		/// 得到实体列表
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetList(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string strSQL = "select * from " + GetTableName() + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.Query<T>(strSQL, param);
		}
		/// <summary>
		/// 得到实体列表（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<IEnumerable<T>> GetListAsync(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string strSQL = "select * from " + GetTableName() + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.QueryAsync<T>(strSQL, param);
		}
		/// <summary>
		/// 得到实体列表
		/// </summary>
		/// <param name="strJoin">联合查询语句(例：inner join tablename t on t.id=t1.id)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetList(string strJoin, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string strSQL = "select * from " + GetTableName() + " " + strJoin + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.Query<T>(strSQL, param);
		}
		/// <summary>
		/// 得到实体列表（异步方式）
		/// </summary>
		/// <param name="strJoin">联合查询语句(例：inner join tablename t on t.id=t1.id)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<IEnumerable<T>> GetListAsync(string strJoin, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string strSQL = "select * from " + GetTableName() + " " + strJoin + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.QueryAsync<T>(strSQL, param);
		}
		#endregion

		#region 得到数据列表
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="selector">返回结果（必须是模型中存在的字段）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<TResult> GetAllData<TResult>(Expression<Func<T, bool>> predicate,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			Expression<Func<T, TResult>> selector = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetAllData<T,TResult>(predicate, orderby, selector, writeAndRead);
		}
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="selector">返回结果（必须是模型中存在的字段）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<IEnumerable<TResult>> GetAllDataAsync<TResult>(Expression<Func<T, bool>> predicate,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			Expression<Func<T, TResult>> selector = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return await GetAllDataAsync<T,TResult>(predicate, orderby, selector, writeAndRead);
		}
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="selector">返回结果（必须是模型中存在的字段）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<TResult> GetAllData<TEntity, TResult>(Expression<Func<TEntity, bool>> predicate,
			Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>> orderby = null,
			Expression<Func<TEntity, TResult>> selector = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
			where TEntity : class
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			var sqlOrderBy = orderby.GetOrderBySql();
			var sqlSelect = selector.GetQueryField();
			return GetAllData<TResult>(GetTableName(typeof(TEntity).Name),sqlWhere + sqlOrderBy, GetDynamicParameters(listSqlParaModel), sqlSelect, writeAndRead);
		}
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="selector">返回结果（必须是模型中存在的字段）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<IEnumerable<TResult>> GetAllDataAsync<TEntity, TResult>(Expression<Func<TEntity, bool>> predicate,
			Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>> orderby = null,
			Expression<Func<TEntity, TResult>> selector = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
			where TEntity : class
		{
			List<SqlParaModel> listSqlParaModel = new List<SqlParaModel>();
			string sqlWhere = (predicate == null) ? string.Empty : predicate.GetWhereSql(listSqlParaModel);
			var sqlOrderBy = orderby.GetOrderBySql();
			var sqlSelect = selector.GetQueryField();
			return await GetAllDataAsync<TResult>(GetTableName(typeof(TEntity).Name), sqlWhere + sqlOrderBy, GetDynamicParameters(listSqlParaModel), sqlSelect, writeAndRead);
		}
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="tableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="strExtended">返回的指定列(例如: extended = id + name 或 distinct name)</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<TResult> GetAllData<TResult>(string tableName, string strWhere = "", object param = null, string strExtended = "*", WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			if (string.IsNullOrEmpty(tableName))
			{
				tableName = GetTableName();
			}
			if (string.IsNullOrEmpty(strExtended))
			{
				strExtended = "*";
			}
			string strSQL = "select " + strExtended + " from " + tableName + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.Query<TResult>(strSQL, param);
		}
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="tableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="strExtended">返回的指定列(例如: extended = id + name 或 distinct name)</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual async Task<IEnumerable<TResult>> GetAllDataAsync<TResult>(string tableName, string strWhere = "", object param = null, string strExtended = "*", WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			if (string.IsNullOrEmpty(tableName))
			{
				tableName = GetTableName();
			}
			if (string.IsNullOrEmpty(strExtended))
			{
				strExtended = "*";
			}
			string strSQL = "select " + strExtended + " from " + tableName + GetSqlWhere(strWhere);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.QueryAsync<TResult>(strSQL, param);
		}
		#endregion

		#region 分页
		/// <summary>
		/// 通过存储过程“Common_GetList”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetListPaged(int startRowIndexId, int maxNumberRows, string Filter, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetListPaged(startRowIndexId, maxNumberRows, "", "", Filter, "", "", out Total, writeAndRead);
		}
		/// <summary>
		/// 通过存储过程“Common_GetList”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetListPaged(int startRowIndexId, int maxNumberRows, string StrColumn, string TableName, string Filter, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			if (string.IsNullOrEmpty(TableName))
			{
				TableName = GetTableName();
			}
			if (string.IsNullOrEmpty(SortColumn))
			{
				SortColumn = AttrHelper.GetKeyName<T>();
			}
			return GetListPaged<T>(startRowIndexId, maxNumberRows, StrColumn, TableName, Filter, SortColumn, Sorts,out Total,writeAndRead);
		}
		/// <summary>
		/// 通过存储过程“Common_GetList”，得到分页后的数据
		/// </summary>
		/// <typeparam name="TResult">实体类</typeparam>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<TResult> GetListPaged<TResult>(int startRowIndexId, int maxNumberRows, string StrColumn, string TableName, string Filter, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			Total = 0;
			if (string.IsNullOrEmpty(SortColumn) || string.IsNullOrEmpty(TableName))
			{
				return null;
			}
			if (string.IsNullOrEmpty(StrColumn))
			{
				StrColumn = "*";
			}
			if (string.IsNullOrEmpty(Sorts))
			{
				Sorts = "DESC";
			}
			string storedProcedureName = "Common_GetList";
			var param = new DynamicParameters();
			param.Add("@StartRows", startRowIndexId);
			param.Add("@PageSize", maxNumberRows);
			param.Add("@StrColumn", StrColumn);
			param.Add("@TableName", TableName);
			param.Add("@Filter", Filter);
			param.Add("@SortColumn", SortColumn);
			param.Add("@Sorts", Sorts);
			param.Add("@Total", dbType: DbType.Int32, direction: ParameterDirection.Output);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			var result = dbContext.Query<TResult>(storedProcedureName, param,CommandType.StoredProcedure);
			Total = param.Get<int>("Total");
			return result;
		}

		/// <summary>
		/// 通过存储过程“Common_GetListBySortColumn”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumnDbType">排序字段的数据类型(如：int)</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetListPagedBySortColumn(int startRowIndexId, int maxNumberRows, string Filter, string SortColumnDbType, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetListPagedBySortColumn(startRowIndexId, maxNumberRows, "", "","", Filter, SortColumnDbType, SortColumn, Sorts, out Total, writeAndRead);
		}
		/// <summary>
		/// 通过存储过程“Common_GetListBySortColumn”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="PrimaryColumn">主键字段名</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumnDbType">排序字段的数据类型(默认：int)</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetListPagedBySortColumn(int startRowIndexId, int maxNumberRows, string PrimaryColumn, string StrColumn, string TableName, string Filter, string SortColumnDbType, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			if (string.IsNullOrEmpty(PrimaryColumn))
			{
				PrimaryColumn = AttrHelper.GetKeyName<T>();
			}
			if (string.IsNullOrEmpty(TableName))
			{
				TableName = GetTableName();
			}
			if (string.IsNullOrEmpty(SortColumnDbType))
			{
				SortColumnDbType = "int";
			}
			if (string.IsNullOrEmpty(SortColumn))
			{
				SortColumn = AttrHelper.GetKeyName<T>();
			}
			return GetListPagedBySortColumn<T>(startRowIndexId, maxNumberRows, PrimaryColumn, StrColumn, TableName, Filter, SortColumnDbType, SortColumn, Sorts, out Total, writeAndRead);
		}
		/// <summary>
		/// 通过存储过程“Common_GetListBySortColumn”，得到分页后的数据
		/// </summary>
		/// <typeparam name="TResult">实体类</typeparam>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="PrimaryColumn">主键字段名</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumnDbType">排序字段的数据类型(如：int)</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<TResult> GetListPagedBySortColumn<TResult>(int startRowIndexId, int maxNumberRows, string PrimaryColumn, string StrColumn, string TableName, string Filter, string SortColumnDbType, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			Total = 0;
			if (string.IsNullOrEmpty(PrimaryColumn) || string.IsNullOrEmpty(SortColumnDbType) || string.IsNullOrEmpty(SortColumn) || string.IsNullOrEmpty(TableName))
			{
				return null;
			}
			if (string.IsNullOrEmpty(StrColumn))
			{
				StrColumn = "*";
			}
			if (string.IsNullOrEmpty(Sorts))
			{
				Sorts = "DESC";
			}
			string storedProcedureName = "Common_GetListBySortColumn";
			var param = new DynamicParameters();
			param.Add("@StartRows", startRowIndexId);
			param.Add("@PageSize", maxNumberRows);
			param.Add("@PrimaryColumn", PrimaryColumn);
			param.Add("@StrColumn", StrColumn);
			param.Add("@TableName", TableName);
			param.Add("@Filter", Filter);
			param.Add("@SortColumnDbType", SortColumnDbType);
			param.Add("@SortColumn", SortColumn);
			param.Add("@Sorts", Sorts);
			param.Add("@Total", dbType: DbType.Int32, direction: ParameterDirection.Output);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			var result = dbContext.Query<TResult>(storedProcedureName, param, CommandType.StoredProcedure);
			Total = param.Get<int>("Total");
			return result;
		}

		/// <summary>
		/// 通过存储过程“Statistics_GetListByPage”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="ID">用于分页的、不重复的字段</param>
		/// <param name="Group">分组语句（例：group by name,sex）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetListPagedByStat(int startRowIndexId, int maxNumberRows, string Filter, string ID, string Group, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetListPagedByStat(startRowIndexId, maxNumberRows, "", "", Filter, "", "", ID, Group, out Total, writeAndRead);
		}
		/// <summary>
		/// 通过存储过程“Statistics_GetListByPage”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="ID">用于分页的、不重复的字段</param>
		/// <param name="Group">分组语句（例：group by name,sex）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<T> GetListPagedByStat(int startRowIndexId, int maxNumberRows, string StrColumn, string TableName, string Filter, string SortColumn, string Sorts, string ID, string Group, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			if (string.IsNullOrEmpty(TableName))
			{
				TableName = GetTableName();
			}
			if (string.IsNullOrEmpty(SortColumn))
			{
				SortColumn = AttrHelper.GetKeyName<T>();
			}
			return GetListPagedByStat<T>(startRowIndexId, maxNumberRows, StrColumn, TableName, Filter, SortColumn, Sorts, ID, Group, out Total, writeAndRead);
		}
		/// <summary>
		/// 通过存储过程“Statistics_GetListByPage”，得到分页后的数据
		/// </summary>
		/// <typeparam name="TResult">实体类</typeparam>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="ID">用于分页的、不重复的字段</param>
		/// <param name="Group">分组语句（例：group by name,sex）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public virtual IEnumerable<TResult> GetListPagedByStat<TResult>(int startRowIndexId, int maxNumberRows, string StrColumn, string TableName, string Filter, string SortColumn, string Sorts, string ID, string Group, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			Total = 0;
			if (string.IsNullOrEmpty(ID) || string.IsNullOrEmpty(Group) || string.IsNullOrEmpty(SortColumn) || string.IsNullOrEmpty(TableName))
			{
				return null;
			}
			if (string.IsNullOrEmpty(StrColumn))
			{
				StrColumn = "*";
			}
			if (string.IsNullOrEmpty(Sorts))
			{
				Sorts = "DESC";
			}
			string storedProcedureName = "Statistics_GetListByPage";
			var param = new DynamicParameters();
			param.Add("@StartRows", startRowIndexId);
			param.Add("@PageSize", maxNumberRows);
			param.Add("@StrColumn", StrColumn);
			param.Add("@TableName", TableName);
			param.Add("@Filter", Filter);
			param.Add("@ID", ID);
			param.Add("@Group", Group);
			param.Add("@SortColumn", SortColumn);
			param.Add("@Sorts", Sorts);
			param.Add("@Total", dbType: DbType.Int32, direction: ParameterDirection.Output);
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			var result = dbContext.Query<TResult>(storedProcedureName, param, CommandType.StoredProcedure);
			Total = param.Get<int>("Total");
			return result;
		}
		#endregion

		#region 执行SQL，检验是否存在数据
		/// <summary>
		/// 执行SQL，检验是否存在数据
		/// </summary>
		/// <param name="tableName"></param>
		/// <param name="strWhere"></param>
		/// <param name="param"></param>
		/// <param name="commandType"></param>
		/// <returns></returns>
		public bool IsExistBySql(string tableName, string strWhere, object param = null, CommandType commandType = CommandType.Text)
		{
			string strSQL = "select count(*) from " + tableName + GetSqlWhere(strWhere);
			if (GetBySQL<int>(strSQL, param) > 0)
			{
				return true;
			}
			return false;
		}
		/// <summary>
		/// 执行SQL，检验是否存在数据
		/// </summary>
		/// <param name="tableName"></param>
		/// <param name="strWhere"></param>
		/// <param name="param"></param>
		/// <param name="commandType"></param>
		/// <returns></returns>
		public async Task<bool> IsExistBySqlAsync(string tableName, string strWhere, object param = null, CommandType commandType = CommandType.Text)
		{
			string strSQL = "select count(*) from " + tableName + GetSqlWhere(strWhere);
			if (await GetBySQLAsync<int>(strSQL, param) > 0)
			{
				return true;
			}
			return false;
		}
		#endregion

		#region 运行SQL语句,返回受影响的行数
		/// <summary>
		/// 执行SQL语句并返回受影响的行数
		/// </summary>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType">是存储过程还是SQL语句</param>
		/// <returns></returns>
		public int ExeSQL(string sql, object param = null, CommandType commandType = CommandType.Text)
		{
			return _Context.Execute(sql, param, commandType);
		}
		/// <summary>
		/// 执行SQL语句并返回受影响的行数（异步）
		/// </summary>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType">是存储过程还是SQL语句</param>
		/// <returns></returns>
		public async Task<int> ExeSQLAsync(string sql, object param = null, CommandType commandType = CommandType.Text)
		{
			return await _Context.ExecuteAsync(sql, param, commandType);
		}
		#endregion

		#region 执行SQL，返回结果
		/// <summary>
		/// 执行SQL，返回结果。例：
		/// var s = testDal.GetBySQL《string》("select name from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《StoreM》("select * from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《dynamic》("select name,Code from tablename where Id=@Id",new { Id = id });
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public TResult GetBySQL<TResult>(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.QueryFirstOrDefault<TResult>(sql, param, commandType);
		}
		/// <summary>
		/// 执行SQL，返回结果。例：
		/// var s = testDal.GetBySQL《string》("select name from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《StoreM》("select * from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《dynamic》("select name,Code from tablename where Id=@Id",new { Id = id });
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public async Task<TResult> GetBySQLAsync<TResult>(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.QueryFirstOrDefaultAsync<TResult>(sql, param, commandType);
		}
		#endregion

		#region 执行SQL，返回结果列表
		/// <summary>
		/// 执行SQL，返回结果。例：
		/// var s = testDal.GetBySQL《string》("select name from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《StoreM》("select * from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《dynamic》("select name,Code from tablename where Id=@Id",new { Id = id });
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IEnumerable<TResult> GetListBySQL<TResult>(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.Query<TResult>(sql, param, commandType);
		}
		/// <summary>
		/// 执行SQL，返回结果。例：
		/// var s = testDal.GetBySQL《string》("select name from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《StoreM》("select * from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《dynamic》("select name,Code from tablename where Id=@Id",new { Id = id });
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public async Task<IEnumerable<TResult>> GetListBySQLAsync<TResult>(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.QueryAsync<TResult>(sql, param, commandType);
		}

		/// <summary>
		/// 执行SQL，返回结果列表。
		/// 使用2种输入类型执行多重映射查询。这将返回一个单一类型，通过映射从原始类型组合而成。
		/// </summary>
		/// <typeparam name="TFirst">记录集中的第一个类型</typeparam>
		/// <typeparam name="TSecond">记录集中的第二个类型</typeparam>
		/// <typeparam name="TResult">要返回的组合类型</typeparam>
		/// <param name="sql">SQL语句</param>
		/// <param name="map">将行类型映射到返回类型的函数</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }）</param>
		/// <param name="splitOn">我们应该拆分并从中读取第二个对象的字段（默认值：“Id”）。</param>
		/// <param name="commandType">是存储过程还是SQL语句</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IEnumerable<TResult> GetListBySQL<TFirst, TSecond, TResult>(string sql, Func<TFirst, TSecond, TResult> map, object param = null, string splitOn = "Id", CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.Query(sql, map,param, splitOn, commandType);
		}
		/// <summary>
		/// 执行SQL，返回结果列表。
		/// 使用2种输入类型执行多重映射查询。这将返回一个单一类型，通过映射从原始类型组合而成。
		/// </summary>
		/// <typeparam name="TFirst">记录集中的第一个类型</typeparam>
		/// <typeparam name="TSecond">记录集中的第二个类型</typeparam>
		/// <typeparam name="TResult">要返回的组合类型</typeparam>
		/// <param name="sql">SQL语句</param>
		/// <param name="map">将行类型映射到返回类型的函数</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }）</param>
		/// <param name="splitOn">我们应该拆分并从中读取第二个对象的字段（默认值：“Id”）。</param>
		/// <param name="commandType">是存储过程还是SQL语句</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public async Task<IEnumerable<TResult>> GetListBySQLAsync<TFirst, TSecond, TResult>(string sql, Func<TFirst, TSecond, TResult> map, object param = null, string splitOn = "Id", CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.QueryAsync(sql, map, param, splitOn, commandType);
		}
		#endregion

		#region 执行SQL，返回DataTable
		/// <summary>
		/// 执行SQL，返回DataTable
		/// </summary>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public DataTable GetDataTableBySql(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return dbContext.GetDataTable(sql, param, commandType);
		}
		/// <summary>
		/// 执行SQL，返回DataTable
		/// </summary>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public async Task<DataTable> GetDataTableBySqlAsync(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var dbContext = (writeAndRead == WriteAndReadEnum.Read) ? _DbContextFactory.CreateDbContext(writeAndRead) : _Context;
			return await dbContext.GetDataTableAsync(sql, param, commandType);
		}
		#endregion

		#region 辅助方法
		private string GetTableName(string tableName = "")
		{
			var result = "";
			if (string.IsNullOrEmpty(tableName))
			{
				result = typeof(T).Name;
			}
			if (result.EndsWith("Entity"))
			{
				result = result.Replace("Entity", "");
			}
			return result;
		}
		private string GetSqlWhere(string strWhere)
		{
			string result = string.Empty;
			if (!string.IsNullOrEmpty(strWhere))
			{
				strWhere = strWhere.Trim();
				if (strWhere.StartsWith("where"))
				{
					result = " " + strWhere;
				}
				else if (strWhere.StartsWith("and"))
				{
					result = " where 1=1 " + strWhere;
				}
				else
				{
					result = " where " + strWhere;
				}
			}
			return result;
		}
		/// <summary>
		/// 生成参数列表
		/// </summary>
		/// <param name="listSqlParaModel"></param>
		/// <returns></returns>
		protected DynamicParameters GetDynamicParameters(List<SqlParaModel> listSqlParaModel)
		{
			var param = new DynamicParameters();
			listSqlParaModel.ForEach(item => {
				param.Add(item.name, item.value);
			});
			return param;
		}
		/// <summary>
		/// 从数据表中获取字段，并生成参数列表。
		/// </summary>
		/// <param name="contentData">包含添加信息内容的数据表：包含FieldType,FieldAsia,FieldLevel,FieldValue字段的数据行</param>
		/// <param name="filter"></param>
		/// <returns></returns>
		protected DynamicParameters GetDynamicParameters(DataTable contentData, string filter)
		{
			var parameters = new DynamicParameters();
			foreach (DataRow row in Query.GetDataRows(contentData, filter))
			{
				object fieldValue = row["FieldValue"];
				FieldType fieldType = (FieldType)Enum.Parse(typeof(FieldType), row["FieldType"].ToString());
				if (fieldType == FieldType.RegionType)
				{
					string[] strArray = row["FieldValue"].ToString().Split(new char[] { ',' });
					parameters.Add(row["FieldName"] + "_Country", strArray[0]);
					parameters.Add(row["FieldName"] + "_Province",strArray[1]);
					parameters.Add(row["FieldName"] + "_City",strArray[2]);
					parameters.Add(row["FieldName"] + "_Area",strArray[3]);
				}
				else if (fieldType == FieldType.RegionTypeFive)
				{
					string[] strArray = row["FieldValue"].ToString().Split(new char[] { ',' });
					parameters.Add(row["FieldName"] + "_Country", strArray[0]);
					parameters.Add(row["FieldName"] + "_Province", strArray[1]);
					parameters.Add(row["FieldName"] + "_City", strArray[2]);
					parameters.Add(row["FieldName"] + "_Area", strArray[3]);
					parameters.Add(row["FieldName"] + "_Area1",strArray[4]);
					parameters.Add(row["FieldName"] + "_Area2",strArray[5]);
				}
				else if (fieldType == FieldType.RegionTypeText)
				{
					string[] strArray = row["FieldValue"].ToString().Split(new char[] { ',' });
					parameters.Add(row["FieldName"] + "_Country", strArray[0]);
					parameters.Add(row["FieldName"] + "_Province", strArray[1]);
					parameters.Add(row["FieldName"] + "_City", strArray[2]);
					parameters.Add(row["FieldName"] + "_Area", strArray[3]);
					parameters.Add(row["FieldName"] + "_Address",strArray[4]);
				}
				else
				{
					parameters.Add(row["FieldName"].ToString(),Query.GetFieldValue(fieldType, fieldValue));
				}
			}
			return parameters;
		}
		#endregion
	}
}
